{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "np.random.seed(1337)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# parameters of the model\n",
    "num_alleles = 64\n",
    "num_genes = 100\n",
    "mutation_rate = 0.05\n",
    "num_pop = 1000\n",
    "ratio_survive = 0.2\n",
    "num_epochs = 200"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# fitness matrix for each gene for each allele\n",
    "F = np.random.randn(num_genes, num_alleles)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 9, 60, 44, 26, 41, 21, 47, 59, 18,  2, 56, 48, 30, 49, 17, 61,  7,\n",
       "       15, 30, 16, 56,  3, 20, 29, 37,  2, 46, 31, 50,  8, 45, 56, 24, 41,\n",
       "       14,  0, 29, 40, 43, 44, 32, 18, 40, 35, 44, 37, 13, 17, 17, 35, 63,\n",
       "       46, 14, 55, 12,  9, 45, 45, 21, 39, 19, 57, 22, 47, 42,  4,  2, 20,\n",
       "        3, 40, 42, 54,  3, 31, 43, 10, 63, 30, 39, 29, 30, 54, 52,  3, 48,\n",
       "       22, 56, 33, 49, 41, 29, 15, 30, 20, 27, 45, 43,  6, 54, 41])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# example chromosome: just an array of allele identities for each gene\n",
    "chromosome = np.random.randint(0, num_alleles, num_genes)\n",
    "chromosome"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 9, 46, 44, 26, 41, 21, 47, 59, 55,  2, 57, 48, 30, 49, 17, 61,  7,\n",
       "       15, 30, 16, 56,  3, 20, 29, 37,  2, 46, 31, 50,  8, 45, 56, 24, 41,\n",
       "       14,  0, 29, 40, 43, 44, 32, 18, 40, 35, 44, 37, 13, 17, 17, 35, 63,\n",
       "       32, 14, 55, 12,  9, 45, 45, 21, 39, 19, 57, 22, 47, 42,  4,  2, 20,\n",
       "        3, 40, 42, 54,  3, 31, 43, 10, 63, 30, 39, 29, 30, 54, 52,  3, 48,\n",
       "       22, 56, 33, 49, 41, 29, 15, 30, 20, 27, 45, 43,  6, 54, 41])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def mutate(ch):\n",
    "  # randomly mutate some parts of chromosome\n",
    "  m = np.random.rand(*ch.shape) <= mutation_rate\n",
    "  return np.where(m, np.random.randint(0, num_alleles, ch.shape), ch)\n",
    "mutate(chromosome)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 9, 63, 44, 26, 41, 21, 47, 59, 18,  2, 56, 48, 30, 49, 17, 61,  7,\n",
       "       15, 30, 16, 56,  3, 20, 29, 37,  2, 46, 31, 14,  8, 45, 56, 24, 41,\n",
       "       14,  0, 29, 40, 43, 44, 32, 18, 40, 35, 44, 37, 13, 17, 17, 35, 63,\n",
       "       46, 14, 35, 12,  9, 45, 45, 21, 39, 19, 57, 22, 47, 42,  4,  2,  2,\n",
       "       57, 40, 42, 54,  3, 31, 43, 10, 63, 30, 39, 29, 30, 54, 52,  3, 48,\n",
       "       22, 56, 33, 49, 41, 29, 15, 30, 20, 27, 45, 43,  6, 54, 41])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def crossover(ch1, ch2):\n",
    "  # randomly mix parts of two chromosomes\n",
    "  m = np.random.rand(*ch1.shape) < 0.5\n",
    "  return np.where(m, ch1, ch2)\n",
    "crossover(mutate(chromosome), mutate(chromosome))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1000, 100)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "seed_chromosome = np.random.randint(0, num_alleles, (1, num_genes))\n",
    "pop = mutate(np.repeat(seed_chromosome, num_pop, axis=0))\n",
    "pop.shape # num_pop x num_genes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "# asexual reproduction model\n",
    "asexual = []\n",
    "pop = mutate(np.repeat(seed_chromosome, num_pop, axis=0))\n",
    "for i in range(num_epochs):\n",
    "  # eval and log current population fitness\n",
    "  fit = F[range(num_genes), pop].mean(1)\n",
    "  asexual.append(float(np.mean(fit)))\n",
    "  # survive the most fit organisms\n",
    "  ix = np.argsort(fit)[::-1]\n",
    "  nsurv = int(ratio_survive * num_pop)\n",
    "  surv = pop[ix[:nsurv]]\n",
    "  # reproduce a new generation via mutation of random surviving organisms\n",
    "  repix = np.random.randint(0, nsurv, num_pop - nsurv)\n",
    "  children = mutate(pop[repix])\n",
    "  pop = np.concatenate((surv, children))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "# sexual reproduction model\n",
    "sexual = []\n",
    "pop = mutate(np.repeat(seed_chromosome, num_pop, axis=0))\n",
    "for i in range(num_epochs):\n",
    "  # eval and log current population fitness\n",
    "  fit = F[range(num_genes), pop].mean(1)\n",
    "  sexual.append(float(np.mean(fit)))\n",
    "  # survive the most fit organisms\n",
    "  ix = np.argsort(fit)[::-1]\n",
    "  nsurv = int(ratio_survive * num_pop)\n",
    "  surv = pop[ix[:nsurv]]\n",
    "  # reproduce a new generation via crossover + mutation of two parents\n",
    "  repix1 = np.random.randint(0, nsurv, num_pop - nsurv)\n",
    "  repix2 = np.random.randint(0, nsurv, num_pop - nsurv)\n",
    "  children = mutate(crossover(pop[repix1], pop[repix2]))\n",
    "  pop = np.concatenate((surv, children))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(asexual, '-r')\n",
    "plt.plot(sexual, '-g')\n",
    "plt.legend(['asexual', 'sexual'])\n",
    "plt.ylabel('fitness mean')\n",
    "plt.xlabel('epoch');"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "# :O"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
